﻿using System.Collections.Generic;
using System.Diagnostics;
using WinRTFramework.Common;
using Windows.UI.Xaml;

namespace DPChangedExtension
{
	public class DemoVM : Bindable
	{
		private readonly List<DemoDataObject> _dataObjects = new List<DemoDataObject>();
		public DemoVM()
		{
			_dataObjects.Add( new DemoDataObject { Name = "Demo Data Object 1" } );
			_dataObjects.Add( new DemoDataObject { Name = "Demo Data Object 2" } );
			_dataObjects.Add( new DemoDataObject { Name = "Demo Data Object 3" } );
			_dataObjects.Add( new DemoDataObject { Name = "Demo Data Object 4" } );
		}

		#region Properties
		private object _demoDataContent;
		public object DemoDataContent
		{
			[DebuggerStepThrough]
			get { return _demoDataContent; }
			set
			{
				if ( value == _demoDataContent )
					return;

				_demoDataContent = value;
				NotifyPropertyChanged( () => DemoDataContent );
			}
		}

		private DemoDataObject _demoDataContext;
		public DemoDataObject DemoDataContext
		{
			[DebuggerStepThrough]
			get { return _demoDataContext; }
			set
			{
				if ( value == _demoDataContext )
					return;

				_demoDataContext = value;
				NotifyPropertyChanged( () => DemoDataContext );
			}
		}

		private Visibility _demoVisibility;
		public Visibility DemoVisibility
		{
			[DebuggerStepThrough]
			get { return _demoVisibility; }
			set
			{
				if ( value == _demoVisibility )
					return;

				_demoVisibility = value;
				NotifyPropertyChanged( () => DemoVisibility );
			}
		}

		private bool _demoIsHitTestVisible;
		public bool DemoIsHitTestVisible
		{
			[DebuggerStepThrough]
			get { return _demoIsHitTestVisible; }
			set
			{
				if ( value == _demoIsHitTestVisible )
					return;

				_demoIsHitTestVisible = value;
				NotifyPropertyChanged( () => DemoIsHitTestVisible );
			}
		}
		#endregion

		#region Commands
		private DelegateCommand _initializeDemoDataCommand;
		public DelegateCommand InitializeDemoDataCommand
		{
			get
			{
				return
					_initializeDemoDataCommand =
					_initializeDemoDataCommand ??
					new DelegateCommand( InitializeDemoDataExecutedHandler, InitializeDemoDataCanExecuteHandler,
										() => DemoDataContent );
			}
		}
		private bool InitializeDemoDataCanExecuteHandler()
		{
			return DemoDataContent == null;
		}
		private void InitializeDemoDataExecutedHandler()
		{
			DemoDataContent = this;
		}

		private DelegateCommand _removeDemoDataCommand;
		public DelegateCommand RemoveDemoDataCommand
		{
			get
			{
				return _removeDemoDataCommand = _removeDemoDataCommand ?? new DelegateCommand( RemoveDemoDataExecutedHandler, RemoveDemoDataCanExecuteHandler,
					() => DemoDataContent );
			}
		}
		private bool RemoveDemoDataCanExecuteHandler()
		{
			return DemoDataContent != null;
		}
		private void RemoveDemoDataExecutedHandler()
		{
			DemoDataContent = null;
		}

		private DelegateCommand _changeDemoDataContextCommand;
		public DelegateCommand ChangeDemoDataContextCommand
		{
			get
			{
				return _changeDemoDataContextCommand =
					   _changeDemoDataContextCommand ??
					   new DelegateCommand( ChangeDemoDataContextExecutedHandler, ChangeDemoDataContextCanExecuteHandler,
										   () => DemoDataContent );
			}
		}
		private bool ChangeDemoDataContextCanExecuteHandler()
		{
			return DemoDataContent != null;
		}
		private void ChangeDemoDataContextExecutedHandler()
		{
			int dataObjectIndex = _dataObjects.IndexOf( DemoDataContext );
			dataObjectIndex++;
			if ( dataObjectIndex >= _dataObjects.Count )
			{
				dataObjectIndex = 0;
			}

			DemoDataContext = _dataObjects[dataObjectIndex];
		}

		private DelegateCommand _changeDemoVisibilityCommand;
		public DelegateCommand ChangeDemoVisibilityCommand
		{
			get
			{
				return
					_changeDemoVisibilityCommand =
					_changeDemoVisibilityCommand ??
					new DelegateCommand( ChangeDemoVisibilityExecutedHandler, ChangeDemoVisibilityCanExecuteHandler,
										() => DemoDataContent );
			}
		}
		private bool ChangeDemoVisibilityCanExecuteHandler()
		{
			return DemoDataContent != null;
		}
		private void ChangeDemoVisibilityExecutedHandler()
		{
			DemoVisibility = DemoVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
		}

		private DelegateCommand _changeDemoIsHitTestVisibleCommand;
		public DelegateCommand ChangeDemoIsHitTestVisibleCommand
		{
			get
			{
				return
					_changeDemoIsHitTestVisibleCommand =
					_changeDemoIsHitTestVisibleCommand ??
					new DelegateCommand( ChangeDemoIsHitTestVisibleExecutedHandler, ChangeDemoIsHitTestVisibleDemoCanExecuteHandler,
										() => DemoDataContent );
			}
		}
		private bool ChangeDemoIsHitTestVisibleDemoCanExecuteHandler()
		{
			return DemoDataContent != null;
		}
		private void ChangeDemoIsHitTestVisibleExecutedHandler()
		{
			DemoIsHitTestVisible = !DemoIsHitTestVisible;
		}
		#endregion
	}

	public class DemoDataObject : Bindable
	{
		public string Name { get; set; }

		public override string ToString()
		{
			return Name;
		}
	}
}